/*
 * RtmpCaster.h
 *
 *  Created on: 2016年9月15日
 *      Author: zhengboyuan
 */

#ifndef RTMPCASTER_H_
#define RTMPCASTER_H_


////////////////////////////////////////////////////////////////////////////

#ifdef WIN32

    #ifndef NOMINMAX
    #define NOMINMAX
    #endif //NOMINMAX

	#include <Windows.h>
#else

#endif //WIN32


////////////////////////////////////////////////////////////////////////////

#ifdef _MSC_VER
    typedef signed char     int8_t;
    typedef unsigned char   uint8_t;
    typedef short           int16_t;
    typedef unsigned short  uint16_t;
    typedef int             int32_t;
    typedef unsigned        uint32_t;
    typedef long long       int64_t;
    typedef unsigned long long   uint64_t;
#else
    #include <stdint.h>
    typedef void*   HANDLE;
#endif //_MSC_VER


///////////////////////////////////////////////////////////////////
#ifdef WIN32
    #ifndef DLLEXPORT
    #define DLLEXPORT __declspec(dllexport)
    #endif //DLLEXPORT
#else
	#ifndef DLLEXPORT
    #define DLLEXPORT __attribute__ ((visibility ("default")))
	#endif //DLLEXPORT
#endif //WIN32

///////////////////////////////////////////////////////////////////
#ifdef __cplusplus
extern "C"
{
#endif

/////////////////////////////////////////////////////////////////////////////
#ifndef MKBETAG
#define MKBETAG(a,b,c,d) ((d) | ((c) << 8) | ((b) << 16) | ((unsigned)(a) << 24))
#endif //MKBETAG

#ifndef CASTER_TYPE
#define	CASTER_TYPE


/// 编码 
enum MCodec
{
    MCODEC_NONE = 0,

    MCODEC_H264 = 28,
	MCODEC_HEVC = 174, /// H.265
	MCODEC_H265 = MCODEC_HEVC,

    MCODEC_G711U = 65542,
    MCODEC_G711A,

    MCODEC_MP3 = 0x15001,
    MCODEC_AAC = 0x15002,
    MCODEC_AC3 = 0x15003,
    MCODEC_VORBIS = 0x15005,
	MCODEC_OPUS = 0x1503d,
	MCODEC_RAW = 0x10101010

};

enum MType
{
    MTYPE_NONE  = -1,
    MTYPE_VIDEO = 0,
    MTYPE_AUDIO,
    MTYPE_DATA,
};


/// 媒体格式 
struct MFormat
{
	int codec;		/// 视频编码  @see MCodec
	int width;		/// 视频高 
	int height;		/// 视频宽 
	int framerate;		/// 帧率 
	int profile;
	int clockRate;  /// 时钟频率 

	int audioCodec;	/// 音频编码  @see MCodec
	int channels;	/// 通道数 
	int sampleRate;	/// 采样率 
	int audioProfile;	/// 档次 
	int audioRate;      /// 音频时钟频率 

	int vPropSize;		/// 视频解码参数, 对于H.264是sps+pps, 对于H.265是vps+sps+pps
	unsigned char* vProp;

	int configSize;		/// 音频解码参数, 如果是AAC编码, 则必须设置为AAC的config参数 
	unsigned char* config;

    int bitrate;    ///码率. 
    int audioBitrate;
};


/// 媒体包 
struct MPacket
{
    int type;       ///
	uint8_t* data;	/// 数据指针 
	int size;		/// 数据长度 
	int64_t pts;	/// 时间戳 
	int duration;	/// 时长 
	int flags;		/// 标识 
};


enum CasterConst
{
	MAX_CASTER = 64,
	INVALID_CASTER = -1
};


typedef int		caster_t;


enum CasterEventType
{
    CASTER_SESSION_REQUEST = 1,
    CASTER_SESSION_CREATE,
    CASTER_SESSION_DESTROY,
};

struct CasterEvent
{
    int  type;
    caster_t  handle;	/// 通道句柄 
    char name[256];		/// 通道名称或者缓存队列数量， 根据type定义 
};


/**
 * 事件回调函数 
 * @param event		事件 
 * @param context	回调环境 
 */
typedef void (*CasterEventCallback)(const CasterEvent* event, void* context);


#endif //CASTER_TYPE


enum RtmpCasterConst
{
	RTMP_PORT = 1935
};

enum RtmpCasterEventType
{
	RTMP_CASTER_CONNECTING  = 0x10,		/// 连接中 
	RTMP_CASTER_CONNECTED	= 0x11,		/// 连接成功 
	RTMP_CASTER_DISCONNECTED= 0x12,		/// 连接断开了 
	RTMP_CASTER_CONNECT_FAULT,			/// 连接失败 

	RTMP_CASTER_DROP_FRAME,	/// 丢帧
	RTMP_CASTER_QUEUE_FULLY,	/// 缓存饱和
	RTMP_CASTER_QUEUE_IDLE	/// 缓存空闲
};

/////////////////////////////////////////////////////////////////////////////


/**
 * 初始化 
 * @return
 */
DLLEXPORT int rtmpcaster_init();

/**
 * 反初始化 
 * @return
 */
DLLEXPORT void rtmpcaster_quit();


/**
 * 打开通道 
 * @param handle 返回的通道句柄 
 * @param url	推送地址 
 * @param fmt   媒体格式 
 * @return 0 表示成功 
 */
DLLEXPORT int rtmpcaster_open(caster_t* handle, const char* url, const MFormat* fmt);

/**
 * 关闭通道 
 * @param handle 通道句柄 
 */
DLLEXPORT void rtmpcaster_close(caster_t handle);


/**
 * 写媒体数据 
 * @param handle
 * @param pkt		媒体包 
 * @return
 */
DLLEXPORT int rtmpcaster_write(caster_t handle, const MPacket* packet);




/**
 * 设置事件回调句柄 
 * @param cb		回调函数指针 
 * @param context	回调环境 
 * @return 0 表示成功 
 */
DLLEXPORT int rtmpcaster_set_event_callback(caster_t handle, CasterEventCallback cb, void* context);


/**
* 获取事件名称
* @param event
* @return
*/
DLLEXPORT const char* rtmpcaster_get_event_name(int event);

/**
* 设置视频缓存大小, 单位为帧个数, 取值应大于GOP. 一般取值为 45
* 当缓存的视频帧超过该阈值时, 触发丢帧(仅保留最近的关键帧)
* @param size	帧数
* @return
*/
DLLEXPORT int rtmpcaster_set_queue_size(int size);

/**
* 设置重连时间间隔, 默认为30秒.
* @param seconds 重连间隔, 单位为秒.
* @return 0 表示成功
*/
DLLEXPORT int rtmpcaster_set_retry_interval(int seconds);

/**
 * 设置线程堆栈大小. = 0 表示系统默认大小.
 * @param stackSize
 */
DLLEXPORT void rtmpcaster_set_stack_size(int stackSize);


/////////////////////////////////////////////////////////////////////////////

#ifdef __cplusplus
}
#endif



#endif /* RTMPCASTER_H_ */
